﻿Imports Microsoft.VisualBasic
Imports System.Collections.Generic
Imports System.Text
Imports System.Web.UI


Namespace Web.UI.Javascript
    Public Class ToolKitTools
        Private FirstAsync As Boolean = True
        Private FirstControl As Boolean = True
        Private CurrentPage As System.Web.UI.Page
        Private Scripts As New Generic.List(Of String)
        Private ScriptsAfterLoad As New Generic.List(Of String)
        Private AjaxTrace As New Generic.List(Of String)
        Private WithEvents CurrentScriptManager As ScriptManager
        Public Sub New()

        End Sub
        Public Sub New(ByVal page As Web.UI.ToolKitPage)
            CurrentPage = page
            CurrentScriptManager = ScriptManager.GetCurrent(CurrentPage)
            Me.RegisterScriptSrc(Me.GetType, "ToolKitVB.ToolKit.js")
            Me.AddLoadFunction("'Clear'")
            Try
                'If CurrentScriptManager IsNot Nothing Then CurrentScriptManager.Services.Add(New ServiceReference(page.ApplicationPath + "/wsErrors.asmx"))
            Catch ex As Exception
                'Dim HandleError As New Errors(ex, "~/ws/ErrorHandler.asmx", "Make sure ErrorHandler.asmx in proper directory")
            End Try
        End Sub
        Public Sub AlertClient(ByVal Message As String)
            Dim AlertScript As String = "alert('" & Message.Replace("'", "\'") & "');"
            If (CurrentScriptManager IsNot Nothing AndAlso DirectCast(CurrentScriptManager, ScriptManager).IsInAsyncPostBack) Then
                AddLoadFunction("function(){" & AlertScript & "}")
            Else
                Scripts.Add(AlertScript)
                CurrentPage.ClientScript.RegisterClientScriptBlock(CurrentPage.GetType, "ErrorMessage" & Scripts.Count, AlertScript, True)
            End If
        End Sub
        ''' <summary>
        ''' RegisterScriptSrc for use in Javscript
        ''' <param name="script">Add Javscript File</param>
        ''' </summary>
        Public Sub RegisterScriptSrc(ByVal SrcType As Type, ByVal Src As String)
            Dim sm As System.Web.UI.ScriptManager = System.Web.UI.ScriptManager.GetCurrent(CurrentPage)
            Dim includeLocation As String = CurrentPage.ClientScript.GetWebResourceUrl(SrcType, Src)
            If sm Is Nothing Then
                If Not Scripts.Contains(includeLocation) Then
                    Dim ScriptHead As New HtmlControls.HtmlGenericControl("script")
                    ScriptHead.Attributes.Add("type", "text/javascript")
                    ScriptHead.Attributes.Add("src", includeLocation)
                    CurrentPage.Header.Controls.Add(ScriptHead)
                    Scripts.Add(includeLocation)
                End If
            Else
                sm.Scripts.Add(New System.Web.UI.ScriptReference(includeLocation))
            End If
        End Sub

        ''' <summary>
        ''' RegisterCssSrc for adding embedded CSS files
        ''' <param name="script">Add Javscript File</param>
        ''' </summary>
        Public Sub RegisterCssSrc(ByVal SrcType As Type, ByVal Src As String)
            Dim includeLocation As String = CurrentPage.ClientScript.GetWebResourceUrl(SrcType, Src)
            If Not Scripts.Contains(includeLocation) Then
                Dim ScriptHead As New HtmlControls.HtmlGenericControl("link")
                ScriptHead.Attributes.Add("rel", "stylesheet")
                ScriptHead.Attributes.Add("text", "text/css")
                ScriptHead.Attributes.Add("href", includeLocation)
                CurrentPage.Header.Controls.Add(ScriptHead)
                Scripts.Add(includeLocation)
            End If
        End Sub

        ''' <summary>
        ''' RegisterControl for use in Javscript
        ''' <param name="script">Control that needs to be used in Javscript</param>
        ''' </summary>
        Public Sub RegisterControl(ByVal cntrl As Control)
            CurrentPage = CType(cntrl.Page, Web.UI.ToolKitPage)
            CurrentScriptManager = ScriptManager.GetCurrent(CurrentPage)
            Dim script As String = ""
            If (CurrentScriptManager IsNot Nothing AndAlso DirectCast(CurrentScriptManager, ScriptManager).IsInAsyncPostBack) Then
                If TypeOf cntrl Is System.Web.UI.WebControls.BaseValidator Then
                    script = "if (ToolKit.exists('" & cntrl.ID & "')){" & cntrl.ID & " = document.getElementById('" & cntrl.ClientID & "');}else{var " & cntrl.ID & " = document.getElementById('" & cntrl.ClientID & "');}"
                Else
                    script = "if (ToolKit.exists('" & cntrl.ID & "')){" & cntrl.ID & " = ObjectVar('" & cntrl.ClientID & "');}else{var " & cntrl.ID & " = ObjectVar('" & cntrl.ClientID & "');}"
                End If
                ScriptManager.RegisterClientScriptBlock(CurrentPage, CurrentPage.GetType, "var" & cntrl.ID, script & vbCrLf, True)
            Else
                If TypeOf cntrl Is System.Web.UI.WebControls.BaseValidator Then
                    script = "var " & cntrl.ID & " = " & cntrl.ClientID & ";"
                Else
                    script = "var " & cntrl.ID & " = document.getElementById('" & cntrl.ClientID & "');"
                End If
                CurrentPage.ClientScript.RegisterStartupScript(CurrentPage.GetType(), "var" & cntrl.ID, script & vbCrLf, True)
            End If

        End Sub
        ''' <summary>
        ''' Fires after page has completely loaded.
        ''' <param name="script">Javscript Function</param>
        ''' </summary>
        Public Sub AddLoadFunction(ByVal script As String)
            Scripts.Add(script)
            If (CurrentScriptManager IsNot Nothing AndAlso DirectCast(CurrentScriptManager, ScriptManager).IsInAsyncPostBack) Then
                ScriptManager.RegisterClientScriptBlock(CurrentPage, CurrentPage.GetType, "Script" & Scripts.Count, "addLoadEvent(" & script & ");" & vbCrLf, True)
                ScriptManager.RegisterClientScriptBlock(CurrentPage, CurrentPage.GetType, "ScriptExecuter", "var toLoadComplete = setTimeout(""onPageLoadComplete();"",100);" & vbCrLf, True)
            Else
                CurrentPage.ClientScript.RegisterStartupScript(CurrentPage.GetType(), "Script" & Scripts.Count, "addLoadEvent(" & script & ");" & vbCrLf, True)
            End If
        End Sub
        ''' <summary>
        ''' Fires after page has completely loaded.
        ''' <param name="script">Javscript Function</param>
        ''' </summary>
        ''' 
        Public Sub OnPageLoaded(ByVal script As String)
            ScriptsAfterLoad.Add(script & vbCrLf)
        End Sub
        Public Function PageLoadedFunctions() As String
            Return vbCrLf & "<script type=""text/Javascript"">" & vbCrLf & "onPageLoadComplete();" & vbCrLf & String.Concat(ScriptsAfterLoad.ToArray()) & vbCrLf & "</script>" & vbCrLf
        End Function
        ''' <summary>
        ''' Fires in case of an AsyncPostBackError...Concatenates a generic list called AjaxList with the errors, and displays the errors to the user.
        ''' </summary>
        Protected Sub CurrentScriptManager_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) Handles CurrentScriptManager.AsyncPostBackError
            'This function actually traps the Ajax expection so we send messages to the user
            'or not show a generic exception, whichever case may be.
            Dim S As New StringBuilder
            With S
                For Each str As String In AjaxTrace
                    .Append(str)
                    .Append(Environment.NewLine)
                Next
                e.Exception.Data("ExtraInfo") = .ToString
            End With
            If TypeOf e.Exception Is Errors.ToolKitClientException Then
                CurrentScriptManager.AsyncPostBackErrorMessage = e.Exception.Message
            ElseIf (Not e.Exception.Data("ExtraInfo") Is Nothing) AndAlso HttpContext.Current.IsDebuggingEnabled Then
                CurrentScriptManager.AsyncPostBackErrorMessage = _
                   e.Exception.Message + _
                   Environment.NewLine + _
                   e.Exception.Data("ExtraInfo").ToString()

                Errors.ToolKitUnexpectedError.Report(e.Exception, e.Exception.Data("ExtraInfo").ToString(), "Caught in Javascript.CurrentScriptManager_AsyncPostBackError")
            Else
                Errors.ToolKitUnexpectedError.Report(e.Exception, "ToolKitTools", "CurrentScriptManager_AsyncPostBackError")
            End If

            If (Not e.Exception.Data("Errors") Is Nothing) Then
                CurrentScriptManager.AsyncPostBackErrorMessage = e.Exception.Data("Errors").ToString
            End If
        End Sub
        ''' <summary>
        ''' Puts Client-Side code in try-catch block.
        ''' Method will not allow nested try/catch blocks.
        ''' </summary>
        ''' <param name="js">Client-Side Script</param>
        ''' <param name="Identifier">Identifier for error log</param>
        ''' <returns>try{[Original Client-Side Script]}catch(ex){errors(ex,'[Identifier]');}</returns>
        Public Shared Function WrapErrorHandler(ByVal js As String, ByVal Identifier As String) As String
            If js.IndexOf("catch(") < 0 Then
                Return "try{" & js & "}catch(ex){ToolKit.errors(ex,'" & Identifier.Replace("'", "\'") & "');}"
            Else
                Return js
            End If
        End Function

    End Class
End Namespace